home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / ply15dat.zip / SPHCOIL.C < prev    next >
C/C++ Source or Header  |  1992-10-04  |  5KB  |  173 lines

  1. /*
  2.  * coil.c - Create a coil of n turns between two points in space
  3.  *
  4.  * Alexander Enzmann
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #ifdef MAC
  11. #include <console.h>
  12. #endif
  13. #include "def.h"
  14. #include "lib.h"
  15.  
  16. static void
  17. determine_coil_point(COORD4 *pos, COORD4 *norm,
  18.              double theta, double phi, double r0, double r1, double d0)
  19. {
  20.    COORD4 v0, v1, vd;
  21.    double len;
  22.  
  23.    /* Center of the coil */
  24.    SET_COORD4(v0, r0 * cos(theta), r0 * sin(theta), d0, 1.0);
  25.  
  26.    /* Point on the coil */
  27.    SET_COORD4(*pos, (r0 + r1 * sin(phi)) * cos(theta),
  28.             (r0 + r1 * sin(phi)) * sin(theta),
  29.             (r1 * cos(phi)) + d0,
  30.             1.0);
  31.  
  32.    /* Direction from center to point */
  33.    SUB3_COORD(vd, *pos, v0);
  34.    len = lib_normalize_coord3(&vd);
  35.  
  36.    v0.x = r1*cos(phi)*cos(theta);
  37.    v1.x = -(r0 + r1*sin(phi))*sin(theta);
  38.  
  39.    v0.y = r1*cos(phi)*sin(theta);
  40.    v1.y = (r0 + r1*sin(phi))*cos(theta);
  41.  
  42.    v0.z = -r1*sin(phi);
  43.    v1.z = 0.0;
  44.  
  45.    CROSS(*norm, v0, v1);
  46.    len = lib_normalize_coord3(norm);
  47.  
  48.    len = DOT_PRODUCT(*norm, vd);
  49.    if (len < 0.0) {
  50.       norm->x *= -1.0;
  51.       norm->y *= -1.0;
  52.       norm->z *= -1.0;
  53.       }
  54.    norm->w = 0.0;
  55. }
  56.  
  57. /* Wrap a coil around a sphere of radius sr, centered at d=t */
  58. static void
  59. generate_cyl_coil(COORD4 *start, COORD4 *end,
  60.          int turns, int step_per_turn,
  61.          double r0, double r1,
  62.          double t, double sr)
  63. {
  64.    int i, j, k;
  65.    COORD4 p, p0, p1, n0;
  66.    COORD4 dir;
  67.    MATRIX trans, itrans;
  68.    double dist, u0, u1, d0, d1, len;
  69.    double deltad, deltau;
  70.    double t0, t1, tm;
  71.    double rt, q, rdif = r0 - r1, sr2 = sr * sr;
  72.  
  73.    SUB3_COORD(dir, *end, *start);
  74.    dist = lib_normalize_coord3(&dir);
  75.  
  76.    /* Figure out the transform to get from the parametrically defined
  77.       coil to the start-end line */
  78.    lib_create_canonical_matrix(itrans, trans, start, &dir);
  79.  
  80.    /* Figure out the lower and upper limits that the sphere will
  81.       affect the coil */
  82.    t0 = dist * t - sr;
  83.    t1 = dist * t + sr;
  84.    tm = (t1 + t0) / 2.0;
  85.  
  86.    /* Calculate the step sizes for making the coil */
  87.    deltad = dist / (double)(turns * step_per_turn);
  88.    deltau = 2.0 * PI / (double)step_per_turn;
  89.  
  90.    /* Start generating the cylinders making up the coil */
  91.    for (i=0,d0=0.0;i<turns;i++) {
  92.       for (j=0;j<step_per_turn;j++,d0+=deltad) {
  93.          d1 = d0 + deltad;
  94.      u0 = (double)j * deltau;
  95.      u1 = u0 + deltau;
  96.      if (d0 > t0 && d0 < t1) {
  97.         q = fabs(d0 - tm);
  98.         q = sqrt(sr2 - q * q);
  99.         if (q > rdif)
  100.            rt = r0 + (q - rdif);
  101.         else
  102.            rt = r0;
  103.         }
  104.      else
  105.         rt = r0;
  106.      determine_coil_point(&p, &n0, u0, 0.0, rt, 0.0, d0);
  107.      lib_transform_coord(&p0, &p, trans);
  108.      p0.w = r1;
  109.      if (d1 > t0 && d1 < t1) {
  110.         q = fabs(d1 - tm);
  111.         q = sqrt(sr2 - q * q);
  112.         if (q > rdif)
  113.            rt = r0 + (q - rdif);
  114.         else
  115.            rt = r0;
  116.         }
  117.      else
  118.         rt = r0;
  119.      determine_coil_point(&p, &n0, u1, 0.0, rt, 0.0, d1);
  120.      lib_transform_coord(&p1, &p, trans);
  121.      p1.w = r1;
  122.      lib_output_cylcone(&p0, &p1, OUTPUT_CURVES);
  123.      lib_output_sphere(&p0, OUTPUT_CURVES);
  124.      }
  125.       }
  126.    /* Cap the end */
  127.    lib_output_sphere(&p1, OUTPUT_CURVES);
  128. }
  129.  
  130. void
  131. main(int argc, char *argv[])
  132. {
  133.     COORD4  back_color, coil_color, dir;
  134.     COORD4  center_pt, end_pt, light;
  135.     COORD4  from, at, up;
  136.  
  137.     MATRIX m1, m2;
  138.  
  139.    /* We are using Polyray */
  140.    lib_set_raytracer(OUTPUT_POLYRAY);
  141.  
  142.     /* output viewpoint */
  143.     SET_COORD(from, 0.0, 7.0,-7.0);
  144.     SET_COORD(at,   0.0, 1.0, 2.0);
  145.     SET_COORD(up,   0.0, 1.0, 0.0);
  146.     lib_output_viewpoint(&from, &at, &up, 30.0, 1.0, 1.0, 256, 256);
  147.  
  148.     /* output background color - dark blue */
  149.     SET_COORD(back_color, 0.039, 0.18, 0.376);
  150.     lib_output_background_color(&back_color);
  151.  
  152.     /* output light source */
  153.     SET_COORD4(light,-10.0, 10.0,-20.0, 0.7);
  154.     lib_output_light(&light);
  155.     SET_COORD4(light, 10.0, 10.0,-20.0, 0.7);
  156.     lib_output_light(&light);
  157.  
  158.     /* output sphere color - blue */
  159.     SET_COORD4(center_pt, 0.0, 1.0, 2.0, 1.5);
  160.     SET_COORD(coil_color, 0.2, 0.2, 1.0);
  161.     lib_output_color(&coil_color, 0.1, 0.1, 0.0, 0.4, 3.0, 0.8, 1.3);
  162.     lib_output_sphere(¢er_pt, OUTPUT_CURVES);
  163.  
  164.     /* output coil color - red */
  165.     SET_COORD(coil_color, 1.0, 0.2, 0.2);
  166.     lib_output_color(&coil_color, 0.2, 0.8, 0.0, 0.4, 5.0, 0.0, 0.0);
  167.  
  168.     /* compute and output coil */
  169.     SET_COORD4(center_pt,-1.0,-1.0, 0.0, 1.0);
  170.     SET_COORD4(end_pt, 1.0, 3.0, 4.0, 1.0);
  171.     generate_cyl_coil(¢er_pt, &end_pt, 24, 72, 1.0, 0.05, 0.5, 1.5);
  172. }
  173.